package com.stevetracey.backup;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.commons.io.DirectoryWalker;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.stevetracey.backup.io.google.GoogleDrive;
import com.stevetracey.common.Configuration;

public class BackupWorker extends DirectoryWalker<BackupJobContext> implements Runnable
{
	private static Log log = LogFactory.getLog(BackupWorker.class);
	
	private BackupJobContext backupContext;
	
	public BackupWorker(BackupJobContext pContext)
	{
		super();
		this.backupContext = pContext;
	}
	
	public void run()
	{
		//initial run
		doBackup();		
	}
	
	private void doBackup()
	{
		File rootFolder = new File(this.backupContext.getLocalSourceFolderPath());
		List<BackupJobContext> results = new ArrayList<BackupJobContext>();
		results.add(this.backupContext);
		try
		{
			//inital run to get local total stats
			this.backupContext.setRunning(false);
			walk(rootFolder, results);
			
			//proper run with file copies
			this.backupContext.setRunning(true);
	
			//set update timer email
			Timer timer = new Timer();
			timer.schedule(new TimerTask() {
				
				@Override
				public void run() {
					Backup.sendSummaryEmail(backupContext);
				}
			}, new Date(), Configuration.getIntValue("file.backup.email.update.interval.minutes") * 1000 * 60);
			
			walk(rootFolder, results);
			
			//stop the interim alerts
			timer.cancel();
		}
		catch (IOException e)
		{
			log.error("Failed traversing files and folders for backup");
		}
		
		this.backupContext.setRunning(false);

		//send email etc
		Backup.sendSummaryEmail(this.backupContext);
		this.backupContext.resetCounters();
	}
	
	
    @SuppressWarnings("rawtypes")
	protected boolean handleDirectory(File directory, int depth, Collection results) 
    {
    	BackupJobContext jobContext = (BackupJobContext) results.iterator().next();
    	if (!jobContext.isRunning()) jobContext.incrementTotalLocalFolders(); //just initial pass to count folders and files
    	return true;
    }

      @SuppressWarnings("rawtypes")
	protected void handleFile(File file, int depth, Collection results) 
      {
    	  BackupJobContext jobContext = (BackupJobContext) results.iterator().next();
    	  if (!jobContext.isRunning())
    	  {
    		  jobContext.incrementTotalLocalFiles();
    		  jobContext.addTotalLocalBytes(file.length());
    	  }
    	  try
    	  {
    		  if (jobContext.isRunning()) 
    		  {
    			  GoogleDrive.syncFile(file, jobContext);
    		  }
    	  }
    	  catch (IOException e)
    	  {
    		  jobContext.addFailedFile(file.getAbsolutePath());
    		  jobContext.addFailedFileBytes(file.length());
    		  log.error("Failed to sync file : " + file.getAbsolutePath());
    	  }
      }
      
}
